﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameEngine.Managers.IManagers;
using GameEngine.Listeners;
using GameEngine.Scenes;
using Microsoft.Xna.Framework;
using System.Diagnostics;
using GameEngine.Camera;
using GameEngine.Entities;
using GameEngine.EntityComponents;

namespace GameEngine.Managers.ConcreteManagers
{
    public class SceneManager : ISceneManager
    {
        #region Fields

        private DateTime lastInput = DateTime.Now;
        private InputManager inputManager;
        private PhysicsManager physicsManager;

        private Stack<Scene> scenes = new Stack<Scene>();
        private Game game;

        #endregion

        public SceneManager(Game game)
        {
            this.game = game;   
        }

        /// <summary>
        /// Initializes this instance.
        /// </summary>
        public void Initialize()
        {
            inputManager = (InputManager)game.Services.GetService(typeof(IInputManager));
            physicsManager = (PhysicsManager)game.Services.GetService(typeof(IPhysicsManager));
        }

        /// <summary>
        /// Updates the sceneManager, which in turn updates the scene at the top of the stack and the physicsManager
        /// </summary>
        /// <param name="gameTime">The game time.</param>
        public void Update(GameTime gameTime)
        {
            if (scenes.Count > 0)
            {
                scenes.Peek().Update(gameTime);
                physicsManager.Update(gameTime, scenes.Peek());
            }
        }

        #region Scenes

        /// <summary>
        /// Clears the scenes.
        /// </summary>
        public void ClearScenes()
        {
            scenes.Clear();
        }

        /// <summary>
        /// Gets the active scenes.
        /// </summary>
        /// <returns></returns>
        public List<Scene> GetActiveScenes()
        {
            List<Scene> sceneList = new List<Scene>();

            foreach (Scene scene in scenes.Reverse<Scene>())
            {
                if (scene.isActive)
                    sceneList.Add(scene);
            }

            return sceneList;
        }

        /// <summary>
        /// Peeks the scene.
        /// </summary>
        /// <returns></returns>
        public Scene PeekScene()
        {
            if (scenes.Count > 0)
            {
                return scenes.Peek();
            }
            return null;
        }

        /// <summary>
        /// Pops the scene.
        /// </summary>
        /// <returns></returns>
        public Scene PopScene()
        {
            if (scenes.Count > 0)
            {
                return scenes.Pop();
            }
            return null;
        }

        /// <summary>
        /// Pushes the scene.
        /// </summary>
        /// <param name="scene">The scene.</param>
        public void PushScene(Scene scene)
        {
            scenes.Push(scene);
        }

#endregion
    }
}